package com.tyylab.kestrel.framework.spring.web.config;

import com.google.common.collect.Lists;
import com.tyylab.kestrel.framework.core.util.ReflectionUtil;
import com.tyylab.kestrel.framework.spring.web.annotation.EnableKestrelServer;
import com.tyylab.kestrel.framework.spring.web.impl.ControllerConfigGenerator;
import com.tyylab.kestrel.framework.spring.web.impl.ControllerGenerator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;

import java.util.List;

@Configuration
public class KestrelServerRegistrar implements ImportBeanDefinitionRegistrar {
    private static final Logger log = LoggerFactory.getLogger(KestrelServerRegistrar.class);

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        ControllerConfigGenerator configGenerator = new ControllerConfigGenerator();
        ControllerGenerator controllerGenerator = new ControllerGenerator( configGenerator );

        // find all interface
        var annotationAttributes = importingClassMetadata.getAnnotationAttributes(EnableKestrelServer.class.getName());
        String[] packageNames = (String [])annotationAttributes.get("apiBasePackages");
        // generate controller
        if (null!= packageNames && packageNames.length > 0) {
            List<Class<?>> interfaces = Lists.newLinkedList();
            for (String packageName : packageNames) {
                interfaces.addAll(ReflectionUtil.loadInterfaces(packageName));
            }

            for (Class<?> api : interfaces) {
                Class clz = controllerGenerator.generate(api);
                // regist bean
                BeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(clz).getBeanDefinition();
                beanDefinition.setAutowireCandidate(true);
                registry.registerBeanDefinition(clz.getSimpleName(), beanDefinition);
            }
        }
    }
}
